﻿/**
 * @file std_vector.h
 * Copyright (c) 2019 Gaaagaa. All rights reserved.
 * 
 * @author  : Gaaagaa
 * @date    : 2019-09-09
 * @version : 1.0.0.0
 * @brief   : 使用 C API 的接口形式实现 向量 容器。
 */

/**
 * The MIT License (MIT)
 * Copyright (c) Gaaagaa. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#ifndef __STD_VECTOR_H__
#define __STD_VECTOR_H__

#include "std_comm.h"

////////////////////////////////////////////////////////////////////////////////

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

////////////////////////////////////////////////////////////////////////////////

//====================================================================

// 
// xstd_vector_t 的相关数据类型定义
// 

#define XVCT_FALSE    XSTD_FALSE
#define XVCT_TRUE     XSTD_TRUE
#define XVCT_NULL     XSTD_NULL

typedef xstd_void_t   xvct_void_t;
typedef xstd_bool_t   xvct_bool_t;
typedef xstd_size_t   xvct_size_t;
typedef xstd_ssize_t  xvct_ssize_t;
typedef xstd_elem_t   xvct_elem_t;
typedef xstd_ctxt_t   xvct_ctxt_t;

/** 声明用于排序操作的比较函数类型 */
typedef xstd_func_compare_t  xvct_fcmp_t;

/** 声明 xstd_vector_t 对象的指针类型 */
typedef struct xstd_vector_t * xvct_this_t;

/** 声明 xstd_vector_t 对象的使用节点迭代器类型 */
typedef struct xvct_node_t * xvct_iter_t;

//====================================================================

// 
// xstd_vector_t 的相关操作接口
// 

/**********************************************************/
/**
 * @brief 返回内部的 sizeof(xstd_vector_t) 值。
 */
xvct_size_t std_vector_sizeof(void);

/**********************************************************/
/**
 * @brief 创建 xstd_vector_t 对象。
 * @note  销毁该接口所返回的对象时，用 @see std_vector_destroy() 实现。
 * 
 * @param [in ] xvct_ctxt : 向量 所存储的节点元素上下文描述信息。
 * 
 * @return xvct_this_t : 返回所创建 xstd_vector_t 对象指针。
 */
xvct_this_t std_vector_create(xvct_ctxt_t xvct_ctxt);

/**********************************************************/
/**
 * @brief 销毁 xstd_vector_t 对象，其由 @see std_vector_create() 所创建。
 */
xvct_void_t std_vector_destroy(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 在指定缓存上创建 xstd_vector_t 对象。
 * @note 
 * 1. 所指定的缓存，其大小不可小于 @see std_vector_sizeof() 的返回值。
 * 2. 销毁该接口所返回的对象时，用 @see std_vector_emplace_destroy() 实现。
 * 
 * @param [in,out] xvct_this : 创建 xstd_vector_t 对象所使用的缓存。
 * @param [in    ] xvct_ctxt : 向量 所存储的节点元素上下文描述信息。
 * 
 * @return xvct_this_t : 返回所创建 xstd_vector_t 对象指针。
 */
xvct_this_t std_vector_emplace_create(
                xvct_this_t xvct_this,
                xvct_ctxt_t xvct_ctxt);

/**********************************************************/
/**
 * @brief 
 * 销毁指定缓存上的 xstd_vector_t 对象，
 * 其由 @see std_vector_emplace_create() 所创建。
 */
xvct_void_t std_vector_emplace_destroy(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的 上下文信息。
 */
xvct_ctxt_t std_vector_ctxt(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的 类型标识。
 */
xvct_size_t std_vector_etype(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象所存储的节点元素数量。
 */
xvct_size_t std_vector_size(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象当前的节点元素容量。
 */
xvct_size_t std_vector_capacity(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 判断 xstd_vector_t 对象是否为空。
 */
xvct_bool_t std_vector_empty(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象可容纳节点元素的最大数量。
 */
xvct_size_t std_vector_maxsize(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象存储节点元素的数组缓存地址。
 */
xvct_elem_t std_vector_data(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象指定索引位置上的 元素。
 * 
 * @param [in ] xvct_this : xstd_vector_t 对象。
 * @param [in ] xvct_vpos : 索引位置。
 * 
 * @return xvct_elem_t : 所存储的元素对象。
 */
xvct_elem_t std_vector_at(xvct_this_t xvct_this, xvct_size_t xvct_vpos);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的前端节点元素。
 */
xvct_elem_t std_vector_front(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的后端节点元素。
 */
xvct_elem_t std_vector_back(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 将一定数量的特定元素值 指派给 xstd_vector_t 对象。
 * @note 
 * 1. 操作完成后，容器的节点数量为指定的 xvct_size 值。
 * 2. 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xvct_size : 指派元素的数量。
 * @param [in    ] xvct_elem : 指派的元素值。
 */
xvct_void_t std_vector_assign(
                xvct_this_t xvct_this,
                xvct_size_t xvct_size,
                xvct_elem_t xvct_elem);

/**********************************************************/
/**
 * @brief 
 * 将一组元素 [ xiter_first, xiter_last ) 指派给 xstd_vector_t 对象。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_first : 指派的元素数组起始地址。
 * @param [in    ] xiter_last  : 指派的元素数组结束地址。
 */
xvct_void_t std_vector_assign_array(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_first,
                xvct_iter_t xiter_last);

/**********************************************************/
/**
 * @brief 使用指定元素值填充 xstd_vector_t 对象指定区域的节点元素。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_first : 填充操作的区域起始节点位置。
 * @param [in    ] xiter_last  : 填充操作的区域结束节点位置。
 * @param [in    ] xvct_elem   : 填充操作所使用的。
 */
xvct_void_t std_vector_fill(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_first,
                xvct_iter_t xiter_last,
                xvct_elem_t xvct_elem);

/**********************************************************/
/**
 * @brief 
 * 调整 xstd_vector_t 对象的内部存储缓存大小，
 * 释放多余空间，以适应当前容纳的节点元素数量。
 */
xvct_void_t std_vector_shrink(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 清空 xstd_vector_t 对象所有存储的节点元素。
 */
xvct_void_t std_vector_clear(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 
 * 在 xstd_vector_t 对象指定位置上插入元素。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xiter_pos : 插入节点的位置。
 * @param [in    ] xvct_elem : 节点所存储的元素。
 * 
 * @return xvct_iter_t : 插入后的节点对应的迭代器位置。
 */
xvct_iter_t std_vector_insert(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos,
                xvct_elem_t xvct_elem);

/**********************************************************/
/**
 * @brief 
 * 以右值 move 操作元素拷贝的方式，
 * 在 xstd_vector_t 对象指定位置上安放新元素。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，
 * 引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xiter_pos : 安放节点的位置。
 * @param [in    ] xvct_elem : 节点所存储的元素。
 * 
 * @return xvct_iter_t : 安放后的节点对应的迭代器位置。
 */
xvct_iter_t std_vector_emplace(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos,
                xvct_elem_t xvct_elem);

/**********************************************************/
/**
 * @brief 在 xstd_vector_t 对象指定位置上插入多个同值元素。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xiter_pos : 插入的位置。
 * @param [in    ] xst_count : 插入的节点元素数量。
 * @param [in    ] xvct_elem : 插入的同值元素。
 * 
 * @return xvct_iter_t : 插入后对应的起始节点迭代器位置。
 */
xvct_iter_t std_vector_insert_n(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos,
                xvct_size_t xst_count,
                xvct_elem_t xvct_elem);

/**********************************************************/
/**
 * @brief 
 * 在 xstd_vector_t 对象指定位置上，插入外部
 * 区段 [ xiter_first, xiter_last ) 的节点元素。
 * @note 
 * 该操作有可能导致 xstd_vector_t 对象扩容，引起外部操作的迭代器无效。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_pos   : 插入的位置。
 * @param [in    ] xiter_first : 待插入区段的节点起始地址。
 * @param [in    ] xiter_last  : 待插入区段的节点结束地址。
 * 
 * @return xvct_iter_t : 返回插入后对应的区段起始节点位置。
 */
xvct_iter_t std_vector_insert_range(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos,
                xvct_iter_t xiter_first,
                xvct_iter_t xiter_last);

/**********************************************************/
/**
 * @brief 删除 xstd_vector_t 对象指定位置上的元素。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xiter_pos : 指定删除操作的节点位置。
 * 
 * @return xvct_iter_t : 返回删除操作后的后继节点位置（迭代器）。
 */
xvct_iter_t std_vector_erase(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_pos);

/**********************************************************/
/**
 * @brief 删除 xstd_vector_t 对象指定区域的节点元素。
 * 
 * @param [in,out] xvct_this   : xstd_vector_t 对象。
 * @param [in    ] xiter_first : 删除操作的区域起始节点位置。
 * @param [in    ] xiter_last  : 删除操作的区域结束节点位置。
 * 
 * @return xvct_iter_t : 返回删除操作后的后继节点位置（迭代器）。
 */
xvct_iter_t std_vector_erase_range(
                xvct_this_t xvct_this,
                xvct_iter_t xiter_first,
                xvct_iter_t xiter_last);

/**********************************************************/
/**
 * @brief 向 xstd_vector_t 对象压入新的节点元素。
 */
xvct_void_t std_vector_push_back(
                xvct_this_t xvct_this,
                xvct_elem_t xvct_elem);

/**********************************************************/
/**
 * @brief 以右值 move 方式，向 xstd_vector_t 对象压入新的节点元素。
 */
xvct_void_t std_vector_push_mback(
                xvct_this_t xvct_this,
                xvct_elem_t xvct_elem);

/**********************************************************/
/**
 * @brief 弹出 xstd_vector_t 对象的末端节点元素。
 */
xvct_void_t std_vector_pop_back(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 
 * 调整 xstd_vector_t 对象当前容纳的节点元素数量。
 * 若调整的数量值大于当前数量（即扩容），则新增的节点元素，
 * 可使用 指定元素值 进行填充。
 * 
 * @param [in,out] xvct_this : xstd_vector_t 对象。
 * @param [in    ] xvct_size : 调整的目标数量。
 * @param [in    ] xvct_elem : 扩容时使用的元素值。
 */
xvct_void_t std_vector_resize(
                xvct_this_t xvct_this,
                xvct_size_t xvct_size,
                xvct_elem_t xvct_elem);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象指定索引位置对应的迭代器。
 * 
 * @param [in ] xvct_this : xstd_vector_t 对象。
 * @param [in ] xvct_vpos : 索引位置。
 * 
 * @return xvct_iter_t : 索引位置对应的迭代器。
 */
xvct_iter_t std_vector_iter(xvct_this_t xvct_this, xvct_size_t xvct_vpos);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的起始节点 迭代器 位置。
 */
xvct_iter_t std_vector_begin(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的结束节点 迭代器 位置。
 */
xvct_iter_t std_vector_end(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 对 xstd_vector_t 对象的迭代器进行前移一个节点位置。
 */
xvct_iter_t std_vector_next(xvct_this_t xvct_this, xvct_iter_t xiter_trav);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的反向起始节点 迭代器 位置。
 */
xvct_iter_t std_vector_rbegin(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的反向结束节点 迭代器 位置。
 */
xvct_iter_t std_vector_rend(xvct_this_t xvct_this);

/**********************************************************/
/**
 * @brief 对 xstd_vector_t 对象的迭代器反向进行前移一个节点位置。
 */
xvct_iter_t std_vector_rnext(xvct_this_t xvct_this, xvct_iter_t xiter_trav);

/**********************************************************/
/**
 * @brief 返回 xstd_vector_t 对象的迭代器对应存储的元素值。
 */
xvct_elem_t std_vector_elem(xvct_this_t xvct_this, xvct_iter_t xiter_trav);

////////////////////////////////////////////////////////////////////////////////

/** 
 * @brief 
 * 为 xstd_vector_t 的基础数据类型容器，
 * 定义简化版操作接口的宏。
 */
#define XSTD_VECTOR_TYPE_FUNC(xtype, xname)         \
                                                    \
static inline xvct_this_t                           \
    std_vector_create_##xname(void)                 \
{                                                   \
    return std_vector_create(&xstd_ctxt_##xname);   \
}                                                   \
                                                    \
static inline xtype                                 \
    std_vector_at_##xname(                          \
        xvct_this_t xvct_this,                      \
        xvct_size_t xvct_vpos)                      \
{                                                   \
    return *(xtype *)std_vector_at(                 \
                        xvct_this,                  \
                        xvct_vpos);                 \
}                                                   \
                                                    \
static inline xtype                                 \
    std_vector_front_##xname(                       \
        xvct_this_t xvct_this)                      \
{                                                   \
    return *(xtype *)std_vector_front(xvct_this);   \
}                                                   \
                                                    \
static inline xtype                                 \
    std_vector_back_##xname(                        \
        xvct_this_t xvct_this)                      \
{                                                   \
    return *(xtype *)std_vector_back(xvct_this);    \
}                                                   \
                                                    \
static inline xvct_void_t                           \
    std_vector_assign_##xname(                      \
                xvct_this_t xvct_this,              \
                xvct_size_t xvct_size,              \
                xtype xvct_elem)                    \
{                                                   \
    std_vector_assign(                              \
            xvct_this,                              \
            xvct_size,                              \
            &xvct_elem);                            \
}                                                   \
                                                    \
static inline xvct_void_t                           \
    std_vector_fill_##xname(                        \
                xvct_this_t xvct_this,              \
                xvct_iter_t xiter_first,            \
                xvct_iter_t xiter_last,             \
                xtype xvct_elem)                    \
{                                                   \
    std_vector_fill(                                \
            xvct_this,                              \
            xiter_first,                            \
            xiter_last,                             \
            &xvct_elem);                            \
}                                                   \
                                                    \
static inline xvct_iter_t                           \
    std_vector_insert_##xname(                      \
            xvct_this_t xvct_this,                  \
            xvct_iter_t xiter_pos,                  \
            xtype xvct_elem)                        \
{                                                   \
    return std_vector_insert(                       \
                xvct_this,                          \
                xiter_pos,                          \
                &xvct_elem);                        \
}                                                   \
                                                    \
static inline xvct_iter_t                           \
    std_vector_insert_n_##xname(                    \
                xvct_this_t xvct_this,              \
                xvct_iter_t xiter_pos,              \
                xvct_size_t xst_count,              \
                xtype xvct_elem)                    \
{                                                   \
    return std_vector_insert_n(                     \
                xvct_this,                          \
                xiter_pos,                          \
                xst_count,                          \
                &xvct_elem);                        \
}                                                   \
                                                    \
static inline xvct_void_t                           \
    std_vector_push_back_##xname(                   \
                xvct_this_t xvct_this,              \
                xtype xvct_elem)                    \
{                                                   \
    std_vector_push_back(xvct_this, &xvct_elem);    \
}                                                   \
                                                    \
static inline xvct_void_t                           \
    std_vector_pop_back_##xname(                    \
                xvct_this_t xvct_this)              \
{                                                   \
    std_vector_pop_back(xvct_this);                 \
}                                                   \
                                                    \
static inline xvct_void_t                           \
    std_vector_resize_##xname(                      \
                xvct_this_t xvct_this,              \
                xvct_size_t xvct_size,              \
                xtype xvct_elem)                    \
{                                                   \
    std_vector_resize(                              \
        xvct_this,                                  \
        xvct_size,                                  \
        &xvct_elem);                                \
}                                                   \
                                                    \
static inline xtype                                 \
    std_vector_elem_##xname(                        \
            xvct_this_t xvct_this,                  \
            xvct_iter_t xiter_trav)                 \
{                                                   \
    return *(xtype *)std_vector_elem(               \
                            xvct_this,              \
                            xiter_trav);            \
}

//====================================================================

XSTD_VECTOR_TYPE_FUNC(xstd_char_t   , char   )  // 对应 xstd_char_t    类型
XSTD_VECTOR_TYPE_FUNC(xstd_uchar_t  , uchar  )  // 对应 xstd_uchar_t   类型
XSTD_VECTOR_TYPE_FUNC(xstd_int8_t   , int8   )  // 对应 xstd_int8_t    类型
XSTD_VECTOR_TYPE_FUNC(xstd_int16_t  , int16  )  // 对应 xstd_int16_t   类型
XSTD_VECTOR_TYPE_FUNC(xstd_int32_t  , int32  )  // 对应 xstd_int32_t   类型
XSTD_VECTOR_TYPE_FUNC(xstd_int64_t  , int64  )  // 对应 xstd_int64_t   类型
XSTD_VECTOR_TYPE_FUNC(xstd_uint8_t  , uint8  )  // 对应 xstd_uint8_t   类型
XSTD_VECTOR_TYPE_FUNC(xstd_uint16_t , uint16 )  // 对应 xstd_uint16_t  类型
XSTD_VECTOR_TYPE_FUNC(xstd_uint32_t , uint32 )  // 对应 xstd_uint32_t  类型
XSTD_VECTOR_TYPE_FUNC(xstd_uint64_t , uint64 )  // 对应 xstd_uint64_t  类型
XSTD_VECTOR_TYPE_FUNC(xstd_long_t   , long   )  // 对应 xstd_long_t    类型
XSTD_VECTOR_TYPE_FUNC(xstd_llong_t  , llong  )  // 对应 xstd_llong_t   类型
XSTD_VECTOR_TYPE_FUNC(xstd_ulong_t  , ulong  )  // 对应 xstd_ulong_t   类型
XSTD_VECTOR_TYPE_FUNC(xstd_ullong_t , ullong )  // 对应 xstd_ullong_t  类型
XSTD_VECTOR_TYPE_FUNC(xstd_float_t  , float  )  // 对应 xstd_float_t   类型
XSTD_VECTOR_TYPE_FUNC(xstd_double_t , double )  // 对应 xstd_double_t  类型
XSTD_VECTOR_TYPE_FUNC(xstd_ldouble_t, ldouble)  // 对应 xstd_ldouble_t 类型
XSTD_VECTOR_TYPE_FUNC(xstd_handle_t , handle )  // 对应 xstd_handle_t  类型

////////////////////////////////////////////////////////////////////////////////

#ifdef __cplusplus
}; // extern "C"
#endif // __cplusplus

////////////////////////////////////////////////////////////////////////////////

#endif // __STD_VECTOR_H__

